package java_thinking.unit_17._17_2_6;

import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.TreeSet;

/**
 * @Desc:   hashCode()在HashSet和LinkedHashSet中是必须的，在覆盖equals方法，总是同时覆盖hashCode
 * @author: cww
 * @DateTime: 2019/4/16 8:56
 */

public class SetType {
    int i ;
    public SetType(int n) {
        i = n;
    }
    public boolean equals(Object o ) {
        return o instanceof SetType && (i == ((SetType)o).i);
    }

    @Override
    public String toString() {
        return Integer.toString(i);
    }
}

class HashType extends SetType {

    public HashType(int n) {
        super(n);
    }
    public int hashCode() {
        return i;
    }
}
class TreeType extends SetType implements Comparable<TreeType> {

    public TreeType(int n) {
        super(n);
    }

    @Override
    public int compareTo(TreeType o) {
        return (o.i < i ? -1 :(o.i == i ? 0 : 1));
    }
}
class TypesForSets {
    static <T> Set<T> fill(Set<T> set,Class<T> type){
        try {
            for (int i = 0; i<10; i++) {
                set.add(type.getConstructor(int.class).newInstance(i));
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return set;
    }
    static <T> void test(Set<T> set,Class<T> type) {
        fill(set,type);
        fill(set,type);
        fill(set,type);
        System.out.println(set);
    }

    public static void main(String[] args) {
        test(new HashSet<>(),HashType.class);
        test(new LinkedHashSet<>(),HashType.class);
        test(new TreeSet<>(),TreeType.class);
        //
        test(new HashSet<>(),SetType.class);
        test(new HashSet<>(),TreeType.class);
        test(new LinkedHashSet<>(),SetType.class);
        test(new LinkedHashSet<>(),TreeType.class);
        //证明哪些方法对于某种特定的Set是必须的
        try {
            //没有实现Comparable的SerType放入TreeSet将抛出
            //java.lang.ClassCastException: java_thinking.unit_17._17_2_6.HashType cannot be cast to java.lang.Comparable
            test(new TreeSet<>(),SetType.class);
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        try {
            test(new TreeSet<>(),HashType.class);
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }
}
